﻿using System;
using System.Collections.Generic;
using System.Text;
using System.Xml;
using System.Reflection;
using System.Collections;
using System.Data;
using System.Runtime.CompilerServices;
using System.Xml.Serialization;
using System.IO;
using Microsoft.VisualBasic;
using Microsoft.VisualBasic.CompilerServices;

using Utility;

namespace Model
{
    // 能水合
    public interface IHydratable
    {
        // Methods
        bool Fill(IDataReader dr);

    }

    //Custom Business Object
    public class CBO
    {

        private static T CreateObject<T>(IDataReader dr) where T : IHydratable, new()
        {
            T objObject = new T();
            if (objObject.Fill(dr) == false)
            {
                HydrateObject(objObject, dr);
            }
            return objObject;
        }

        private static void HydrateObject(object objObject, IDataReader dr)
        {
            Type enumType = null;
            ArrayList propertyInfo = GetPropertyInfo(objObject.GetType());
            int[] ordinals = GetOrdinals(propertyInfo, dr);
            int num2 = propertyInfo.Count - 1;
            for (int i = 0; i <= num2; i++)
            {
                PropertyInfo objPropertyInfo = (PropertyInfo)propertyInfo[i];
                enumType = objPropertyInfo.PropertyType;
                if (objPropertyInfo.CanWrite && (ordinals[i] != -1))
                {
                    object objectValue = RuntimeHelpers.GetObjectValue(dr.GetValue(ordinals[i]));
                    Type o = objectValue.GetType();
                    if (Information.IsDBNull(RuntimeHelpers.GetObjectValue(objectValue)))
                    {
                        objPropertyInfo.SetValue(RuntimeHelpers.GetObjectValue(objObject), RuntimeHelpers.GetObjectValue(Null.SetNull(objPropertyInfo)), null);
                    }
                    else if (enumType.Equals(o))
                    {
                        objPropertyInfo.SetValue(RuntimeHelpers.GetObjectValue(objObject), RuntimeHelpers.GetObjectValue(objectValue), null);
                    }
                    else
                    {
                        try
                        {
                            if (enumType.BaseType.Equals(typeof(Enum)))
                            {
                                if (Versioned.IsNumeric(RuntimeHelpers.GetObjectValue(objectValue)))
                                {
                                    objPropertyInfo.SetValue(RuntimeHelpers.GetObjectValue(objObject), RuntimeHelpers.GetObjectValue(Enum.ToObject(enumType, Convert.ToInt32(RuntimeHelpers.GetObjectValue(objectValue)))), null);
                                }
                                else
                                {
                                    objPropertyInfo.SetValue(RuntimeHelpers.GetObjectValue(objObject), RuntimeHelpers.GetObjectValue(Enum.ToObject(enumType, RuntimeHelpers.GetObjectValue(objectValue))), null);
                                }
                            }
                            else if (enumType.FullName.Equals("System.Guid"))
                            {
                                Guid guid = new Guid(objectValue.ToString());
                                objPropertyInfo.SetValue(RuntimeHelpers.GetObjectValue(objObject), RuntimeHelpers.GetObjectValue(Convert.ChangeType(guid, enumType)), null);
                            }
                            else
                            {
                                objPropertyInfo.SetValue(RuntimeHelpers.GetObjectValue(objObject), RuntimeHelpers.GetObjectValue(Convert.ChangeType(RuntimeHelpers.GetObjectValue(objectValue), enumType)), null);
                            }
                        }
                        catch (Exception exception1)
                        {
                            ProjectData.SetProjectError(exception1);
                            objPropertyInfo.SetValue(RuntimeHelpers.GetObjectValue(objObject), RuntimeHelpers.GetObjectValue(Convert.ChangeType(RuntimeHelpers.GetObjectValue(objectValue), enumType)), null);
                            ProjectData.ClearProjectError();
                        }
                    }
                }
            }
        }

        private static ArrayList GetPropertyInfo(Type objType)
        {
            ArrayList cache = (ArrayList)DataCache.GetCache(objType.FullName);
            if (cache == null)
            {
                cache = new ArrayList();
                foreach (PropertyInfo info in objType.GetProperties())
                {
                    cache.Add(info);
                }

                DataCache.SetCache(objType.FullName, cache);
            }
            return cache;
        }

        private static int[] GetOrdinals(ArrayList objProperties, IDataReader dr)
        {
            int[] numArray = new int[objProperties.Count + 1];
            Hashtable hashtable = new Hashtable();
            if (dr != null)
            {
                int num;
                int num2 = dr.FieldCount - 1;
                for (num = 0; num <= num2; num++)
                {
                    hashtable[dr.GetName(num).ToUpper()] = "";
                }
                int num3 = objProperties.Count - 1;
                for (num = 0; num <= num3; num++)
                {
                    string key = ((PropertyInfo)objProperties[num]).Name.ToUpper();
                    if (hashtable.ContainsKey(key))
                    {
                        numArray[num] = dr.GetOrdinal(key);
                    }
                    else
                    {
                        numArray[num] = -1;
                    }
                }
            }
            return numArray;
        }

        public static List<T> FillCollection<T>(IDataReader dr) where T : IHydratable, new()
        {
            List<T> list2 = new List<T>();
            if (dr != null)
            {
                while (dr.Read())
                {
                    T item = CreateObject<T>(dr);
                    list2.Add(item);
                }
                dr.Close();
            }
            return list2;
        }

        public static IList<T> FillCollection<T>(IDataReader dr, ref IList<T> objToFill) where T : IHydratable, new()
        {
            if (dr != null)
            {
                while (dr.Read())
                {
                    T item = CreateObject<T>(dr);
                    objToFill.Add(item);
                }
                dr.Close();
            }
            return objToFill;
        }

        public static T FillObject<T>(IDataReader dr) where T : IHydratable, new()
        {
            return FillObject<T>(dr, true);
        }

        public static T FillObject<T>(IDataReader dr, bool ManageDataReader) where T : IHydratable, new()
        {
            bool flag;
            T local2;
            if (ManageDataReader)
            {
                flag = false;
                if (dr.Read())
                {
                    flag = true;
                }
            }
            else
            {
                flag = true;
            }


            if (flag)
            {
                local2 = CreateObject<T>(dr);
            }
            else
            {
                local2 = new T();
            }
            if (ManageDataReader && (dr != null))
            {
                dr.Close();
            }

            return local2;
        }

        public static XmlDocument Serialize(object objObject)
        {
            XmlSerializer serializer = new XmlSerializer(objObject.GetType());
            StringBuilder sb = new StringBuilder();
            TextWriter textWriter = new StringWriter(sb);
            serializer.Serialize(textWriter, objObject);
            StringReader reader = new StringReader(textWriter.ToString());
            DataSet set = new DataSet();
            set.ReadXml(reader);
            XmlDocument document2 = new XmlDocument();
            document2.LoadXml(set.GetXml());
            return document2;
        }
    }


}
